from django.utils import timezone
from rest_framework import status
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.decorators import action
from fgr_api.views.fgr_apis import printLabelByOrderNo
import tsl_backend.users.models as users
import tsl_backend.frontend_api.models.workorder as workorders
import logging

class PrintLabelView(ViewSet):

    # http_method_names = ['post']
    permission_classes = [IsAuthenticated]
    authentication_classes = [JWTAuthentication]

    @action(detail=False, methods=['post'], url_path='getPrinterInfo')
    def getPrinterInfo(self, request):

        logging.info(f"Request from {request.user} for getPrinterInfo: {request.data}")
        try:
            if request.data["accID"] is None: raise MissingParamException
        except MissingParamException:
            return Response(
                {"detail": "Missing Parameter(s)"},
                status=status.HTTP_400_BAD_REQUEST
            )
        else:

            account_obj = users.Account.objects.filter(id=request.data["accID"]).first()

            printersObjs = users.Printer.objects.all().order_by("department", "description")

            dept_name = account_obj.department.name
            logging.info(f"User department is {dept_name}")

            if '石仓' in dept_name:
                logging.info(f"Search printer for 石仓")
                account_dept = 2
            else:
                logging.info(f"Search printer for 金仓")
                account_dept = 1

            default_printers = users.Printer.objects.filter(department = account_dept, site=account_obj.department.site.name)
            if default_printers.exists():
                default_filter_printers=default_printers.filter(default=True)
                if default_filter_printers.exists():
                    default_printer = default_filter_printers.first()
                else:
                    default_printer = default_printers.first()
            else:
                default_printer = printersObjs.first()

            printers = [{
                "printId": printer.pk,
                "description": printer.description,
                "department": printer.get_department_display(),
            } for printer in printersObjs] 

            return Response(
                {
                    "defaultPrinter": {
                        "printId": default_printer.pk,
                        "description": default_printer.description,
                        "department": default_printer.get_department_display(),
                    },
                    "printerChoices" : printers
                },
                status=status.HTTP_200_OK
            )
        
    @action(detail=False, methods=['post'], url_path='searchPrinterLabel')
    def searchPrinterLabel(self, request):
        logging.info(f"Request from {request.user} for searchPrinterLabel: {request.data}")
        try:
            if request.data["orderNo"] is None and request.FILES["file"] is None: raise MissingParamException
            logging.debug(f"request post: {request.POST}")
            logging.debug(f"request data: {request.data}")

        except MissingParamException:
            return Response(
                {"detail": "Missing Parameter(s)"},
                status=status.HTTP_400_BAD_REQUEST
            )
        else:
            # Return values
            wolist = []
            unknownlist = []
            
            if request.data["orderNo"] != "null":
                orderNo = request.data["orderNo"]
                logging.info(f"orderNo: {orderNo}")
                wo = workorders.Detail.objects.filter(order=orderNo).first()
                logging.info(f"wo: {wo}")
                if wo: 
                    wod = {
                        "serialNo": 1,
                        "orderNo" : wo.order,
                        "site": wo.site.name if wo.site else None,
                        "source": wo.source or "",
                        "designNum": wo.design,
                        "goldType": wo.gold_type,
                        "qty": wo.quantity,
                        "goldPrintDate": wo.gold_print_date.strftime("%Y.%m.%d") if wo.gold_print_date else "未打印",
                        "stonePrintDate": wo.stone_print_date.strftime("%Y.%m.%d") if wo.stone_print_date else "未打印",
                        "printStatus": True if wo.gold_print_date else False
                    }
                    wolist.append(wod) 
                else:
                    unknownlist.append(orderNo)

            elif request.FILES["file"] != "null":
                # read csv file
                file = request.FILES["file"]
                file_data = file.read().decode("utf-8-sig")
                file_output = file_data.split()
                logging.info(f'file_output: {file_output}')

                # Search in database & Store to list
                # orderNo, site, designNum, goldType, qty, goldPrintDate, stonePrintDate
                
                serialNo = 1
                for item in file_output:
                    wo = workorders.Detail.objects.filter(order=item).first()
                    if wo:
                        wod = {
                            "serialNo": serialNo,
                            "orderNo" : wo.order,
                            "site": wo.site.name if wo.site else None,
                            "source": wo.source or "",
                            "designNum": wo.design,
                            "goldType": wo.gold_type,
                            "qty": wo.quantity,
                            "goldPrintDate": wo.gold_print_date.strftime("%Y.%m.%d") if wo.gold_print_date else "未打印",
                            "stonePrintDate": wo.stone_print_date.strftime("%Y.%m.%d") if wo.stone_print_date else "未打印",
                            "printStatus": True if wo.gold_print_date else False
                        }
                        wolist.append(wod)
                        serialNo += 1
                    else:
                        unknownlist.append(item)
                
                logging.info(f"wolist: {wolist}")
                logging.info(f"unknownlist: {unknownlist}")

            return Response(
                {
                    "woList": wolist,
                    "unknownList": unknownlist
                },
                status=status.HTTP_200_OK
            )
        
    @action(detail=False, methods=['post'], url_path='printLabel')
    def printLabel(self, request):
        logging.info(f"Request from {request.user} for printLabel: {request.data}")
        try:
            if request.data["printerID"] is None: raise MissingParamException
            if request.data["printLabelList"] is None: raise MissingParamException
        except MissingParamException:
            return Response(
                {"detail": "Missing Parameter(s)"},
                status=status.HTTP_400_BAD_REQUEST
            )
        else:
            orderNos = request.data["printLabelList"]
            selectedPrinter_pk = request.data["printerID"]
            accID = request.data["accID"]
            printer = users.Printer.objects.get(pk=selectedPrinter_pk)
            description = printer.description 
            groupId = printer.group
            site = printer.site
            printer_id = printer.printId
            staffId=request.user.staffcode

            print_date = '打印不成功'

            try:
                account_obj = users.Account.objects.get(pk=accID)
            except Exception as e:
                logging.error(f"Fail to get account information for account ID: {accID}")
                return Response(
                {
                    "print_date": print_date,
                    "status": True
                    
                },
                status=status.HTTP_200_OK
            )

            printLabelList = [ { "orderNo": order, "seqNo": i+1 }for i, order in enumerate(orderNos)]
           
            logging.info(f"printLabelList: {printLabelList}")
            logging.info(f"printer description: {description}")
            logging.info(f"printer site: {site}")
            logging.info(f"staffId: {staffId}")

            userCode = account_obj.user_code
            user_role = account_obj.role.chinese_name

            res=printLabelByOrderNo(printLabelList, str(printer_id), str(site), str(groupId), staffId, userCode)

            if res["status"]:
                # fgr_status=True
                # update print date
                now = timezone.now()
                print_date = now.strftime("%Y.%m.%d")

                order_list = [ order["orderNo"] for order in printLabelList]
                if user_role == "金仓":
                    logging.info("update gold_print_date")
                    detail_objs = workorders.Detail.objects.filter(
                        order__in=order_list
                    )
                    if detail_objs.exists():
                        detail_objs.update(gold_print_date=now)
                        logging.info(f"update work order gold print data: {order_list}")
                    else:
                        logging.warn(f"Print label list does not exist: {order_list}. Cannot update work order gold print data.")


                elif user_role == "石仓":
                    logging.info("update stone_print_date")
                    detail_objs = workorders.Detail.objects.filter(
                        order__in=order_list
                    )
                    logging.info(f"update stone print date for orders: {detail_objs.exists()}")
                    if detail_objs.exists():
                        detail_objs.update(stone_print_date=now)
                        logging.info(f"update work order stone print data: {order_list}")
                    else:
                        logging.warn(f"Print label list does not exist: {order_list}. Cannot update work order stone print data.")
                else:
                    logging.info(f"Other roles, do not update print status")
            else:
                # fgr_status=False
                logging.warn("Fail to send request to FGR")
                print_date = '打印不成功'

            return Response(
                {
                    "print_date": print_date,
                    "status": res['status'],
                    "message": res['message']
                    
                },
                status=status.HTTP_200_OK
            )

class MissingParamException(Exception):
    """Missing Required Parameter!"""
    pass
